﻿#define  _CRT_SECURE_NO_WARNINGS  1
#include <stdio.h>
#include <ctype.h>
//字符函数和字符串函数
//1.字符分类函数

//int main()
//{
//	//int ret = isupper('X');
//	int ret = islower('a');
//	if (ret)
//		printf("是小写\n");
//	else
//		printf("是大写\n");
//	return 0;
//}

//int main()
//{
//	int ret = isdigit('X'); //isdigit 十进制数字--‘0’--‘9’字符
//	if (ret)
//		printf("%d", ret);
//	return 0;
//}

//写⼀个代码，将字符串中的⼩写字⺟转⼤写，其他字符不变。
//int main()
//{
//	char str[30] = "Hi,i am a Student.";
//	     //         01                \0
//	int  i = 0;
//	while (str[i])
//	{
//		if (islower(str[i]))
//		{
//			//str[i] = str[i] - 32;
//			str[i]=toupper(str[i]);//将参数传过去的小写字母转大写
//		}
//		i++;
//	}
//	printf("%s\n", str);
//	return 0;
//}

//int main()
//{
//	int ret = tolower('W');
//	int rul = toupper('s');
//	printf("%c\n", ret);
//	printf("%c\n", rul);
//	return 0;
//}


#include <string.h>
//int main()
//{
//	char arr[] = "abcdef";
//	//size_t len = strlen(arr);
//	size_t len = strlen(arr + 1);
//	//strlen 从给定的起始位置开始，向后统计\0之前字符的个数
//	printf("%zd\n", len);
//	return 0;
//}

//strlen的返回类型是size_t类型的:无符号的整形类型  无符号整数没有原码、反码、补码之分
//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[] = "abc";
//	//if (strlen(arr2) - strlen(arr1) > 0)
//	//if(strlen(arr2)>strlen(arr1))
//	if((int)strlen(arr2)-(int)strlen(arr1)>0)
//		printf(">\n");
//	else
//		printf("<\n");
//	return 0;
//}

//strlen函数的模拟实现
//计数器的方法
#include <assert.h>
//size_t my_strlen(const char* str)//限制*str，防止str被修改
//{
//	size_t count = 0;
//	assert(str != NULL);
//	while (*str)
//	{
//		count++;
//		str++;
//	}
//	return count;
//}



//指针-指针
//size_t my_strlen(const char* str)
//{
//	const char* start = str;
//	assert(str);
//	while (*str)
//	{
//		str++;
//	}
//	return str - start;
//}


//递归的写法  a b c d e f \0
//            a b c d e+1 
//size_t my_strlen(const char* str)//"abc"
//{
//	if (*str == '\0')// 'a'
//		return 0;
//	else       //1+1+1+0
//		return 1+my_strlen(str+1); // "bc"
//}
//size_t my_strlen(const char* str)//"bc"
//{
//	if (*str == '\0')
//		return 0;
//	else        //1+1+0
//		return 1 + my_strlen(str + 1);//"c"
//}
//size_t my_strlen(const char* str)//"c"
//{
//	if (*str == '\0')
//		return 0;
//	else       //1+0
//		return 1 + my_strlen(str + 1);//"\0"
//}
//size_t my_strlen(const char* str)//"\0"
//{
//	if (*str == '\0')
//		return 0; //0
//	else
//		return 1 + my_strlen(str + 1);
//}
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len = my_strlen(arr);
//	printf("%zd\n", len);
//	return 0;
//}

//strcpy函数
//int  main()
//{
//	char arr1[] = "abcdef";//条件：源字符串必须以‘\0'结束
//	//char arr2[30] = { 0 };
//	//char arr2[30] = "xxxxxxxxxx";//会将原字符串中的‘\0’拷贝到目标空间
//	strcpy(arr2, arr1);//拷贝字符串
//	printf("%s\n", arr2);
//	return 0;
//}
//int main()
//{
//	char arr1[] = { 'a','b','c' };//错误的示范  源字符串必须以‘\0’结束
//	char arr2[30] = "xxxxxxxxxxxxxx";
//	strcpy(arr2, arr1);
//	printf("%s\n", arr2);
//	return 0;
//}

//int main()
//{
//	            char arr1 = "hello";
//错误的写法	char* p = "abcdefxxxx";//常量字符串   确保目的指针是可以被修改的
//	            strcpy(p, arr1);
//	            printf("%s\n", p);
//	            return 0;
//}
//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[] = { 0 };//错误的示范   确保目标空间必须足够大，以确保能存放源字符串
//	strcpy(arr2, arr1);
//	printf("%s\n", arr2);
//	return 0;
//}

//strcpy函数的模拟实现
//void my_strcpy(char* dest, const char* src)
//{
//	while (*src)
//	{
//		*dest = *src;
//		src++;
//		dest++;
//	}
//	*dest = *src;//将原字符串中的‘\0'拷贝到目标空间中
//}
//void my_strcpy(char* dest, const char* src)
//{
//	while (*dest++=*src++)//拿赋值表达式，即能拷贝字符串，又能作为循环的结束条件
//	{
//		;
//	}
//	*dest = *src;//将原字符串中的‘\0'拷贝到目标空间中
//}

//strcpy函数的返回类型是char *类型的
//返回的是目的函数的起始地址
//char* my_strcpy(char* dest, const char* src)
//{
//	//assert(dest != NULL);
//	//assert(src);
//	assert(dest && src);
//	char* ret = dest;
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}
//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[30] = { 0 };
//    // my_strcpy(arr2, arr1); 
//	char* ret = my_strcpy(arr2, arr1);
//	size_t len =strlen (my_strcpy(arr2, arr1));
//	printf("%zd\n", len);
//	printf("%s\n", ret);
//	return 0;
//}


//strcat函数
//int main()
//{
//	//char arr1[30] = "hello ";
//	//strcat(arr1, "world");
//	//1. 找到目标空间中的第一个\0
//	//2. 然后从这个\0的位置开始追加源头字符串
//	char arr2[30] = "xxxxxxx\0xxxxxxxx";//3. 源头字符串的内容，包括\0都会追加到目标空间
//	strcat(arr2, "hello");
//	//printf("%s\n", arr1);
//	return 0;
//}

//strcat的模拟实现
//char* my_strcat(char* dest, char* src)
//{
//	char* p = dest;
//	while (*dest)
//	{
//		dest++;
//	}
//	while (*dest = *src)
//	{
//		dest++;
//		src++;
//	}
//	*dest = *src;
//	return p;
//}
//int main()
//{
//	char arr1[30] = "hello ";
//	char arr2[] = "world";
//	char * p=my_strcat(arr1, arr2);
//	printf("%s\n", p);
//	return 0;
//}

//char* my_strcat(char* dest, const char* src)
//{
//	char* ret = dest;
//	assert(dest&&src);
//	//找到目标空间中的第一个\0
//	while (*dest != '\0')
//		dest++;
//	//拷贝数据
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}
//int main()
//{
//	char arr1[20] = "hello ";
//	//my_strcat(arr1, "world");
//	//printf("%s\n", arr1);
//	char * ret=my_strcat(arr1, "world");
//	printf("%s\n", ret);
//	return 0;
//}

//char* my_strcat(char* dest, const char* src)//dest和src取的是同一块地址  dest走到‘\0’的位置，str在起始的地址处，就是这里的字符h，h将\0给覆盖了，导致死循环
//{
//	char* ret = dest;
//	assert(dest && src);
//	//找到目标空间中的第一个\0
//	while (*dest != '\0')
//		dest++;
//	//拷贝数据
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}
//int main()
//{
//	char arr1[20] = "hello ";
//	my_strcat(arr1, arr1);//自己追加自己，会导致死循环 
//	printf("%s\n", arr1);
//	return 0;
//}

